package com.oa.tools.jobs;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;

import com.oa.tools.TkMapper;
import com.oa.tools.dao.FlowLogDAO;
import com.oa.tools.dao.LbpmProcessDAO;
import com.oa.tools.dao.OAFlowInstanceDAO;
import com.oa.tools.dao.OrgElementDAO;
import com.oa.tools.dao.OrgElementWithPersonDAO;
import com.oa.tools.dao.PersonDAO;
import com.oa.tools.dao.ProjectAccountDAO;
import com.oa.tools.dao.StampDAO;
import com.oa.tools.entity.Person;
import com.oa.tools.jobs.impl.AddNewCYCPeopleTask;
import com.oa.tools.jobs.impl.AddNewFinacialCompanyTask;
import com.oa.tools.jobs.impl.AddNewPeopleTask;
import com.oa.tools.jobs.impl.AddNewStampTask;
import com.oa.tools.jobs.impl.AddNewWYCPeopleTask;
import com.oa.tools.jobs.impl.DelPersonTask;
import com.oa.tools.jobs.impl.FlowBlockMonitorTask;
import com.oa.tools.jobs.impl.FlowErrorMonitorTask;
import com.oa.tools.jobs.impl.UpdatePersonDeptTask;
import com.oa.tools.jobs.impl.UpdatePersonDeptTmpTask;
import com.oa.tools.jobs.impl.UpdateStampKeeperTask;
import com.oa.tools.utils.MailUtil;
import com.oa.tools.utils.SecurityUtil;
import com.oa.tools.utils.StringUtil;
import com.oa.tools.utils.SysConfig;

import tk.mybatis.mapper.entity.Example;

@Service
public class DynamicJob implements Runnable {

	public static boolean jobRunningFlag = false;
	private ScheduledFuture<?> future;
	private long lastestDateMill = System.currentTimeMillis() - 1000L * 60 * 60 * 12*2*10;
	private String cronStr = "0 0/5 * * * ?";

	@Autowired
	private ThreadPoolTaskScheduler threadPoolTaskScheduler;
	@Autowired
	OAFlowInstanceDAO oAFlowInstanceDAO;
	@Autowired
	FlowLogDAO flowLogDAO;
	@Autowired
	PersonDAO personDAO;
	@Autowired
	StampDAO stampDAO;
	@Autowired
	OrgElementDAO orgElementDAO;
	@Autowired
	LbpmProcessDAO lbpmProcessDAO;
	@Autowired
	ProjectAccountDAO projectAccountDAO;
	@Autowired
	OrgElementWithPersonDAO orgElementWithPersonDAO;
	

	public static final Logger logger = LoggerFactory.getLogger(DynamicJob.class);
	private Map<String,FlowHandlerTaskBase> taskMap = new HashMap<>();
	private Map<String,TkMapper<?>> daoMap = new HashMap<>();
	
	public Map<String, FlowHandlerTaskBase> getTaskMap() {
		return taskMap;
	}

	public String chgPass(String email,String mobile) throws Exception {
		
		if(StringUtil.isBlank(email)||StringUtil.isBlank(mobile)) {
			return "邮箱和手机不能为空";
		}
		
		if(!email.endsWith("@fengbangleasing.com")) {
			email = (email+"@fengbangleasing.com").replaceAll("\\s", "");
		}
		
		Example example = new Example(Person.class);
		example.createCriteria().andEqualTo("fdMobileNo", mobile).andEqualTo("fdEmail", email);
		Person obj = this.personDAO.selectOneByExample(example);
		if(obj==null) {
			return "邮箱和手机不匹配";
		}
		
		String newPass = SecurityUtil.getStringRandom(6);
		String newPassMd5 = SecurityUtil.MD5(newPass);
		obj.setFdLockTime(new Date(0));
		obj.setFdPassword(newPassMd5);
		personDAO.updateByPrimaryKeySelective(obj);
		String content = "<pre>Dear "+obj.getFdLoginName()+":\r\n\t\t您的OA新密码为："+newPass+"\r\n\t\t请尽快修改密码</pre> <br/><br/><br/><br/>"+
				"<a href='"+SysConfig.domainName+"/j_acegi_security_check?j_username="+obj.getFdLoginName()+"&j_password="+newPass+"'>点击直达OA系统</a><br/>"+
				"<img src='http://oa-tool.fengbangleasing.com/images/chg-pass.png'>";
				
				
		logger.info(content);
		MailUtil.sendMail(new String[] {email}, "密码重置成功", content);
		
		return "密码已发送到邮箱";
	}

	public long getLastestDateMill() {
		return this.lastestDateMill;
	}

	public void setLastestDateMill(long lastestDateMill) {
		this.lastestDateMill = lastestDateMill;
	}


	@Override
	public void run() {
		try {
			init();
			if(!jobRunningFlag) {
				jobRunningFlag = true;
				long lastestDateMill_tmp = this.lastestDateMill;
				this.lastestDateMill = System.currentTimeMillis() - 1000L * 60 * 60 * 12;
				
				for(String key:taskMap.keySet()) {
					FlowHandlerTaskBase p = taskMap.get(key);
					p.start(true,false,lastestDateMill_tmp);
				}
				
				logger.info("任务执行完成"+System.currentTimeMillis());
			}else{
				logger.info("上一次任务执行未完成");
				return ;
			}
			
			jobRunningFlag = false;
		} catch (Throwable e) {
			jobRunningFlag = false;
			e.printStackTrace();
		}

	}

	public String startCron() {
		future = threadPoolTaskScheduler.schedule(this, new CronTrigger(cronStr));
		return "startCron";
	}

	public String stopCron() {
		if (future != null) {
			future.cancel(true);
		}
		return "stopCron";
	}

	public String update(String cron) {
		stopCron();// 先停止，在开启.
		this.cronStr = cron;
		future = threadPoolTaskScheduler.schedule(this, new CronTrigger(cron));
		return "changeCron10";
	}

	public String getCronStr() {
		return cronStr;
	}

	public void setCronStr(String cronStr) {
		this.cronStr = cronStr;
	}
	
	public void init() {
		if(taskMap.size()==0) {
			daoMap.put("OAFlowInstanceDAO", this.oAFlowInstanceDAO);
			daoMap.put("FlowLogDAO", this.flowLogDAO);
			daoMap.put("PersonDAO", this.personDAO);
			daoMap.put("StampDAO", this.stampDAO);
			daoMap.put("OrgElementDAO", this.orgElementDAO);
			daoMap.put("LbpmProcessDAO", this.lbpmProcessDAO);
			daoMap.put("ProjectAccountDAO", this.projectAccountDAO);
			daoMap.put("OrgElementWithPersonDAO", this.orgElementWithPersonDAO);
			
			
			taskMap.put("AddNewStampTask",new AddNewStampTask(daoMap));
			
			taskMap.put("AddNewFinacialCompanyTask",new AddNewFinacialCompanyTask(daoMap));
			
			taskMap.put("AddNewWYCPeopleTask",new AddNewWYCPeopleTask(daoMap));
			
			taskMap.put("AddNewCYCPeopleTask",new AddNewCYCPeopleTask(daoMap));
			
			taskMap.put("UpdateStampKeeperTask",new UpdateStampKeeperTask(daoMap));
			
			taskMap.put("AddNewPeopleTask",new AddNewPeopleTask(daoMap));
			
			taskMap.put("DelPersonTask",new DelPersonTask(daoMap));
			
			taskMap.put("UpdatePersonDeptTmpTask",new UpdatePersonDeptTmpTask(daoMap));
			
			taskMap.put("UpdatePersonDeptTask",new UpdatePersonDeptTask(daoMap));
			
			taskMap.put("FlowErrorMonitorTask",new FlowErrorMonitorTask(daoMap));
			
			taskMap.put("FlowBlockMonitorTask",new FlowBlockMonitorTask(daoMap));
			
			
		}
	}

}